package com.ray.base.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ray.base.builder.MaterialModelBuilder;
import com.ray.base.builder.PropBuilder;
import com.ray.base.check.MaterialCheck;
import com.ray.base.check.MaterialModelCheck;
import com.ray.base.service.BaseMaterialExtendService;
import com.ray.base.service.BaseMaterialModelService;
import com.ray.base.service.BaseMaterialService;
import com.ray.base.service.BaseMaterialTemplateService;
import com.ray.base.service.compose.GoodsService;
import com.ray.base.table.dto.MaterialModelQueryDTO;
import com.ray.base.table.entity.BaseMaterial;
import com.ray.base.table.entity.BaseMaterialExtend;
import com.ray.base.table.entity.BaseMaterialModel;
import com.ray.base.table.params.material.model.MaterialModelCreateParams;
import com.ray.base.table.params.material.model.MaterialModelEditParams;
import com.ray.base.table.params.material.model.MaterialModelQueryParams;
import com.ray.base.table.vo.material.PropVO;
import com.ray.base.table.vo.material.model.MaterialModelVO;
import com.ray.system.builder.CommonPageBuilder;
import com.ray.validate.support.utils.ValidateUtil;
import com.ray.woodencreate.beans.LoginUser;
import com.ray.woodencreate.enums.YesOrNoEnum;
import com.ray.woodencreate.exception.BusinessExceptionFactory;
import com.ray.woodencreate.page.CommonPage;
import com.ray.woodencreate.result.MsgCodeConstant;
import com.ray.woodencreate.result.Result;
import com.ray.woodencreate.result.ResultFactory;
import com.ray.woodencreate.util.Assert;
import com.ray.woodencreate.util.LogInUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author bo shen
 * @Description: 产品规格相关服务
 * @Class: MaterialModelApi
 * @Package com.ray.base.api
 * @date 2020/5/27 11:15
 * @company <p>Ray快速开发平台</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
@Service
@Slf4j
public class MaterialModelApi {

    @Autowired
    private BaseMaterialModelService baseMaterialModelService;
    @Autowired
    private BaseMaterialService baseMaterialService;
    @Autowired
    private BaseMaterialExtendService baseMaterialExtendService;
    @Autowired
    private BaseMaterialTemplateService baseMaterialTemplateService;
    @Autowired
    private GoodsService goodsService;
    /**
     * 查询产品规格列表信息 分页  非删除的
     *
     * @param queryParams
     * @return
     */
    public Result<IPage<MaterialModelVO>> pageMaterialModels(CommonPage<MaterialModelQueryParams, Page<MaterialModelVO>> queryParams) {
        Assert.notNull(queryParams, "参数[queryParams]不存在");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        CommonPageBuilder<MaterialModelQueryDTO, BaseMaterialModel> commonPageBuilder = new CommonPageBuilder<>(MaterialModelQueryDTO.class);
        commonPageBuilder.appendEntity(queryParams.getEntity()).appendQuery(queryParams.getQuery()).appendPage(queryParams.getPage());
        IPage<BaseMaterialModel> page = baseMaterialModelService.page(commonPageBuilder.bulid(), loginUser);
        List<BaseMaterialModel> materials = page.getRecords();
        //结果对象
        IPage<MaterialModelVO> pageList = new Page<>();
        pageList.setTotal(page.getTotal());
        pageList.setCurrent(page.getCurrent());
        pageList.setSize(page.getSize());
        //查询到结果 数据转换
        if (ObjectUtil.isNotNull(materials)) {
            pageList.setRecords(materials.stream().map(sysMaterialModel -> {
                MaterialModelVO materialModelVO = goodsService.queryGoodsByCode(sysMaterialModel.getModelCode(),loginUser);
                return materialModelVO;
            }).collect(Collectors.toList()));
        } else {
            pageList.setRecords(new ArrayList<>());
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, pageList);
    }

    /**
     * 查询产品规格列表信息--启用的产品规格
     *
     * @param queryParams
     * @return
     */
    public Result<List<MaterialModelVO>> queryMaterialModels(MaterialModelQueryParams queryParams) {
        Assert.notNull(queryParams, "参数[queryParams]不存在");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        Map<String,BaseMaterial> materialMap = new HashMap<>();
        MaterialModelQueryDTO queryDTO = new MaterialModelQueryDTO();
        BeanUtil.copyProperties(queryParams, queryDTO);
        queryDTO.setStatus(YesOrNoEnum.YES.getValue());
        List<BaseMaterialModel> materials = baseMaterialModelService.list(queryDTO, loginUser);
        //查询对象
        List<MaterialModelVO> list = new ArrayList<>();
        if (ObjectUtil.isNotNull(materials)) {
            list = materials.stream().map(sysMaterialModel -> {
                MaterialModelVO materialModelVO  = goodsService.queryGoodsByCode(sysMaterialModel.getModelCode(),loginUser);
                return materialModelVO;
            }).collect(Collectors.toList());
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, list);
    }


    /**
     * 创建产品规格
     *
     * @param createParams 创建对象
     * @return Result
     */
    @Transactional
    public Result<String> createMaterialModel(MaterialModelCreateParams createParams) {
        ValidateUtil.validate(createParams);
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //查询
        BaseMaterial baseMaterial = baseMaterialService.queryMaterialByMaterialCode(createParams.getMaterialCode(), loginUser);
        new MaterialCheck(baseMaterial).checkNull("物料不存在");
        //判断MaterialName是否存在
        BaseMaterialModel baseMaterialModel = baseMaterialModelService.queryMaterialModelByModelName(createParams.getMaterialCode(),
                createParams.getModelName(),loginUser);
        new MaterialModelCheck(baseMaterialModel).checkModelName(null, "规格已经存在");
        MaterialModelBuilder materialBuilder = new MaterialModelBuilder();
        materialBuilder.append(createParams).appendName(baseMaterial.getMaterialName()).appendMaterialType(baseMaterial.getMaterialType())
                .appendStatus(YesOrNoEnum.YES.getValue()).appendCreate(loginUser);
        //保存产品规格信息
        if (!baseMaterialModelService.save(materialBuilder.bulid())) {
            log.info("保存产品规格接口异常,参数:{}", JSON.toJSONString(materialBuilder.bulid()));
            throw BusinessExceptionFactory.newException(MsgCodeConstant.Error.ERR00000001);
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, materialBuilder.getCode());
    }

    /**
     * 编辑产品规格
     *
     * @param editParams 编辑对象
     * @return Result
     */
    @Transactional
    public Result<String> editMaterialModel(MaterialModelEditParams editParams) {
        ValidateUtil.validate(editParams);
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        BaseMaterialModel sysMaterialModel = baseMaterialModelService.queryMaterialModelByMaterialModelCode(editParams.getModelCode(), loginUser);
        new MaterialModelCheck(sysMaterialModel).checkNull("物料规格不存在");
        //判断MaterialName是否存在
        BaseMaterialModel baseMaterialModel = baseMaterialModelService.queryMaterialModelByModelName(sysMaterialModel.getMaterialCode(),
                editParams.getModelName(),loginUser);
        new MaterialModelCheck(baseMaterialModel).checkModelName(editParams.getModelCode(), "规格已经存在");
        MaterialModelBuilder materialBuilder = new MaterialModelBuilder();
        materialBuilder.append(editParams).appendEdit(loginUser);
        //编辑产品规格信息
        if (!baseMaterialModelService.edit(materialBuilder.bulid(), loginUser)) {
            log.info("编辑产品规格接口异常,参数:{}", JSON.toJSONString(materialBuilder.bulid()));
            throw BusinessExceptionFactory.newException(MsgCodeConstant.Error.ERR00000001);
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, materialBuilder.getCode());
    }


    /**
     * 删除产品规格
     *
     * @param materialCode 产品规格编码
     * @return Result
     */
    @Transactional
    public Result<String> deleteMaterialModel(String materialCode) {
        ValidateUtil.hasLength(materialCode, "参数[materialCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        BaseMaterialModel sysMaterialModel = baseMaterialModelService.queryMaterialModelByMaterialModelCode(materialCode, loginUser);
        new MaterialModelCheck(sysMaterialModel).checkNull("物料规格不存在");
        MaterialModelBuilder materialBuilder = new MaterialModelBuilder();
        materialBuilder.appendCode(materialCode).appendEdit(loginUser).delete();
        //删除产品规格信息
        if (!baseMaterialModelService.edit(materialBuilder.bulid(), loginUser)) {
            log.info("删除产品规格接口异常,参数:{}", JSON.toJSONString(materialBuilder.bulid()));
            throw BusinessExceptionFactory.newException(MsgCodeConstant.Error.ERR00000001);
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, materialBuilder.getCode());
    }

    /**
     * 开启产品规格
     *
     * @param materialCode 产品规格编码
     * @return Result
     */
    @Transactional
    public Result<String> openMaterialModel(String materialCode) {
        ValidateUtil.hasLength(materialCode, "参数[materialCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        BaseMaterialModel sysMaterialModel = baseMaterialModelService.queryMaterialModelByMaterialModelCode(materialCode, loginUser);
        new MaterialModelCheck(sysMaterialModel).checkNull("物料规格不存在");
        MaterialModelBuilder materialBuilder = new MaterialModelBuilder();
        materialBuilder.appendCode(materialCode).appendEdit(loginUser).open();
        //开启产品规格信息
        if (!baseMaterialModelService.edit(materialBuilder.bulid(), loginUser)) {
            log.info("开启产品规格接口异常,参数:{}", JSON.toJSONString(materialBuilder.bulid()));
            throw BusinessExceptionFactory.newException(MsgCodeConstant.Error.ERR00000001);
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, materialBuilder.getCode());
    }

    /**
     * 开启产品规格
     *
     * @param materialCode 产品规格编码
     * @return Result
     */
    @Transactional
    public Result<String> closeMaterialModel(String materialCode) {
        ValidateUtil.hasLength(materialCode, "参数[materialCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        BaseMaterialModel sysMaterialModel = baseMaterialModelService.queryMaterialModelByMaterialModelCode(materialCode, loginUser);
        new MaterialModelCheck(sysMaterialModel).checkNull("物料规格不存在");
        MaterialModelBuilder materialBuilder = new MaterialModelBuilder();
        materialBuilder.appendCode(materialCode).appendEdit(loginUser).close();
        //关闭产品规格信息
        if (!baseMaterialModelService.edit(materialBuilder.bulid(), loginUser)) {
            log.info("关闭产品规格接口异常,参数:{}", JSON.toJSONString(materialBuilder.bulid()));
            throw BusinessExceptionFactory.newException(MsgCodeConstant.Error.ERR00000001);
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, materialBuilder.getCode());
    }

    /**
     * 产品规格详情
     *
     * @param materialCode 产品规格编码
     * @return Result
     */
    public Result<MaterialModelVO> viewMaterialModel(String materialCode) {
        ValidateUtil.hasLength(materialCode, "参数[materialCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //获取权限信息
        BaseMaterialModel sysMaterialModel = baseMaterialModelService.queryMaterialModelByMaterialModelCode(materialCode, loginUser);
        new MaterialModelCheck(sysMaterialModel).checkNull("物料规格不存在");
        MaterialModelVO materialModelVO = new MaterialModelVO();
        BeanUtil.copyProperties(sysMaterialModel, materialModelVO);
        BaseMaterial  baseMaterial = baseMaterialService.queryMaterialByMaterialCode(sysMaterialModel.getMaterialCode(),loginUser);
        materialModelVO.setUnit(baseMaterial.getUnit());
        materialModelVO.setMaterialName(baseMaterial.getMaterialName());
        materialModelVO.setMaterialType(baseMaterial.getMaterialType());
        //查询扩展信息
        //获取扩展信息
        Map<String, BaseMaterialExtend> extendMap = baseMaterialExtendService.listByMaterialCode(sysMaterialModel.getMaterialCode()).stream()
                .collect(Collectors.toMap(item -> item.getProp(), item -> item));
        //获取属性信息
        List<PropVO> propVOS = baseMaterialTemplateService.listByComapnyCode(loginUser).stream().map(baseMaterialTemplate -> {
            return new PropBuilder().append(baseMaterialTemplate).append(extendMap.get(baseMaterialTemplate.getProp())).bulid();
        }).collect(Collectors.toList());
        materialModelVO.setProps(propVOS);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, materialModelVO);
    }

}
